﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FaceWebServer.DB.Device;
using FaceWebServer.DB.User;
using FaceWebServer.Interface;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Ruanmou.Redis.Service;
using DoNetDrive.Common.Extensions;

namespace FaceWebServer.Service
{
    /// <summary>
    /// 人脸机设备操作服务
    /// </summary>
    public class FaceDriveService : BaseService, IFaceDriveService
    {
        public FaceDriveService(DbContext context) : base(context)
        {

        }


        public bool Add(FaceDeviceDetail oDevice)
        {
            FaceDeviceDetail oDBModel = GetDetail(oDevice.DeviceID);
            if (oDBModel == null)
            {
                oDBModel = Insert<FaceDeviceDetail>(oDevice);
                UpdateCache(oDevice);
                return true;
            }
            else
            {
                return true;
            }
        }

        public DbSet<FaceDeviceDetail> GetDBSet()
        {
            return this.Context.Set<FaceDeviceDetail>();
        }

        #region 默认值
        public FaceDeviceDetail GetDefaultValue()
        {
            var sysdb = GetSystemKVDBSet();
            var kv = sysdb.Find("DefaultDevice");
            FaceDeviceDetail par = new();
            if (kv == null)
            {
                par = GetDefaultBaseParameter();
            }
            else
            {
                try
                {
                    par = JsonConvert.DeserializeObject<FaceDeviceDetail>(kv.Value);
                }
                catch (Exception)
                {

                    par = GetDefaultBaseParameter();
                }

            }

            return par;
        }


        /// <summary>
        /// 获取默认的出厂参数
        /// </summary>
        /// <returns></returns>
        private FaceDeviceDetail GetDefaultBaseParameter()
        {
            FaceDeviceDetail target = new();
            target.DeviceID = "FC-8280T00000000";//设备ID
            target.ParameterVolume = 84;//音量大小(范围0-84)
            target.ParameterPreview = 1;//活体检测,1打开，0关闭
            //target.ParameterMoreFace = 0;//设置多人脸检测值
            target.ParameterPolling = 10;//主动触发云端轮训时间（以秒为单位）
            target.ParameterLightTimeout = 30;//白补光灯亮灭时间
            target.ParameterLightSwitch = 1;//补光灯开关：0:关闭，1：打开(补光灯打开才能设置自动补光)
            target.ParameterLightActive = 1;//自动补光：0:关闭，1：打开
            target.ParameterFaceThreshold = 90;//人脸识别阈值
            target.ParameterTempThresholdMax = 45;//温度比对阈值（最大值）
            target.ParameterTempThresholdMin = 30;//温度比对阈值（最小值）
            target.ParameterTempPattern = 1;//体温筛选，0关闭，1打开
            //target.ParameterSystemTime = 0;//同步系统时间（时间戳，比如：1584427174对应是2020-03-1714:39:34）
            target.ParameterSaveExternalvisitors = 1;//是否存储非雇员识别记录，0:不存储，1:存储
            target.ParameterMask = 1;//1：打开口罩检测，其他：关闭
            target.ParameterCompensate = 0;//0~1000,温度补偿值
            target.ParameterLoginPassword = "";//菜单密码
            /*
            target.ParameterNetworkSwitch = 1;//有线网络开关，1:打开，0:关闭
            target.ParameterNetworkIpActive = 1;//有线网络自动ip，1:开，0:关
            target.ParameterNetworkIpUrl = "192.168.1.150";//有线网络Ip地址(“//192.168.0.110”)
            target.ParameterNetworkSubnetMask = "255.255.255.0";//有线网络子网掩码(“//255.255.255.0”)
            target.ParameterNetworkGteway = "192.168.1.1";//有线网络网关(“//192.168.0.1”)
            target.ParameterNetworkDns = "114.114.114.114";//Dns(“//192.168.0.1”)
            target.ParameterWifiSwitch = 0;//无线网开关，1:开，0:关
            target.ParameterWifiName = src.ParameterWifiName;//无线网账号
            target.ParameterWifiPassWord = src.ParameterWifiPassWord;//无线网密码
            target.ParameterHotspotSwitch = src.ParameterHotspotSwitch;//热点开关,1:开，0:关
            target.ParameterHotspotName = src.ParameterHotspotName;//热点账号
            target.ParameterHotspotPassword = src.ParameterHotspotPassword;//热点密码
            target.ParameterFirmwareMsg = src.ParameterFirmwareMsg;//固件版本信息
            */
            target.ParameterFahrenheitSwitch = 1;//开启华氏温度,1:开，0:关
            target.ParameterBdhc = 200;//海曼模组DBHC参数，范围200-400
            target.ParameterBdlc = 400;//海曼模组DBLC参数，范围200-400
            target.ParameterCent = "0918";//海曼模组测温中心点坐标参数，限制4位数、必须都是数字（如0918、1616）
            target.ParameterSavePicture = 1;//保存现场图片 0，不保存；1，保存
            target.ParameterAccessType = 0;//出入类型0,入门；1，出门
            target.ParameterWgFormat = 34;//WG输出格式26/34
            target.ParameterKeepOpenDoor = 3;//开门保持时间1-65535（s）
            target.ParameterLaissezSwitch = 1;//免验证开门1--启用；0--禁用
            target.ParameterRecgInterval = 5;//识别间隔0--禁用;1-65535（s）
            target.ParameterIntervalRecoSwitch = 1;//间隔记录存储设置0,关闭；1，打开
            target.ParameterDoorSensor = 0;//门磁类型	0，常闭；1，常开；2，无
            target.ParameterDoorSensorDelay = 60;//开门超时时间，门打开超过这个时间就报警	5-255（s）
            target.ParameterDoorAlarmSwitch = 1;//门磁报警，0，关闭；1，开启
            target.ParameterMaskThreshold = 70;//口罩阈值
            target.ParameterCompanyName = "";//主界面设置--公司名称
            target.ParameterVoiceMode = 3;//语音模式0,不播报；1，播放名字;2,播放问候语;3,播放名字和问候语
            target.ParameterGrettings = 0;//问候语0，请通行;1,欢迎光临;2，时间问候语
            target.ParameterStrangerVoice = 2;//陌生人语音0，不播报;1,播报假体;2，播报陌生人；3，播报假体和陌生人
            target.ParameterBrightness = 1;//亮度设置1-10
            target.ParameterLanguageChoose = 0;//语言选择0，中文；1，英文；2，繁体
            target.ParameterDistance = 100;//识别距离50-150（cm）
            target.ParameterCloudserverAddress = "";//服务器地址
            target.ParameterSerialNum = target.DeviceID;//序列号
            target.ParameterManufacturer = "FCARD";//制造商
            target.ParameterWebsite = "http://www.pc15.net";//网址
            target.ParameterProductionDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");//生产日期

            return target;
        }
        #endregion



        public FaceDeviceDetail GetDetail(string sn)
        {
            FaceDeviceDetail oDevice;
            string sKey = $"FC8280TServer:Device:{sn}";

            using (var redis = new RedisHashService())
            {
                if (redis.ContainsKey(sKey))
                {
                    oDevice = redis.GetAllEntriesFromHash(sKey).ToJSON().FromJson<FaceDeviceDetail>();
                }
                else
                {
                    //去查数据库
                    oDevice = GetDetailByDB(sn);
                    if (oDevice != null)
                    {
                        redis.SetRangeInHash(sKey, oDevice.ToJSON().FromJson<Dictionary<string, string>>());
                    }
                }
                return oDevice;
            }

        }

        public void UpdateCache(FaceDeviceDetail oDevice)
        {
            string sKey = $"FC8280TServer:Device:{oDevice.DeviceID}";

            using (var redis = new RedisHashService())
            {
                redis.SetRangeInHash(sKey, oDevice.ToJSON().FromJson<Dictionary<string, string>>());
            }
        }

        private FaceDeviceDetail GetDetailByDB(string sn)
        {
            var devices = Query<FaceDeviceDetail>(x => x.DeviceID.Equals(sn)).Take(1);
            if (devices.Count() == 0)
            {
                return null;
            }
            var device = devices.First();
            return device;
        }

        public (int NewPeople, int DelPeople, int RemoteCount) GetTaskDetail(string sn)
        {
            var ret = (NewPeople: 0, DelPeople: 0, RemoteCount: 0);
            
            using (var redis = new RedisHashService())
            {
                string sKey = $"FC8280TServer:Access:{sn}";
                var oValues = redis.GetAllEntriesFromHash(sKey);
                try
                {
                    ret.NewPeople = int.Parse(oValues["NewTotal"]);
                    ret.DelPeople = int.Parse(oValues["DeleteTotal"]);
                    ret.RemoteCount = int.Parse(oValues["TaskTotal"]);
                }
                catch (Exception)
                {

                    ;
                }
                
            }
            return ret;
        }
    }
}
